;; supercollider/ugen-assistants.scm - (c) rohan drape, 2003-2004

;; Generate a 'spec' list for a Klang UGen.  `freqs' is a
;; list that determines the number of partials, `amps' and
;; `phases' are possibly abbreviated lists subject to
;; expansion by 'list-expand' to the length of `freqs'.

(defineK (Klang.spec (freqs (440)) (amps (1)) (phases (0)))
  (let ((l (length freqs)))
    (interleave freqs (expand amps l) (expand phases l))))

;; Generate a 'spec' list for a Klank UGen.  `freqs' is a
;; list that determines the number of filters, `amps' and
;; `times' are possibly abbreviated lists subject to expansion
;; by 'list-expand' to the length of `freqs'.

(defineK (Klank.spec (freqs (440)) (amps (1)) (times (1)))
  (let ((l (length freqs)))
    (interleave freqs (expand amps l) (expand times l))))

;; Mix the list of UGen records at `inputs'.  This is an idiom over
;; the nary math operator 'Add'.

(define (Mix inputs) (apply Add inputs))

;; Idiom that uses the zero or one argument procedure `contructor' to
;; build a list of `degree' places, and the 'Mix'es that list.

(define (Mix.fill degree constructor)
  (Mix (tabulate* degree constructor)))

;; The values reguired for the characters #\1, #\q, #\a and #\z
;; respectively.  To determine these under X use the xev(1) command.

(define-global KeyStateIntegerOffsets '(10 24 38 52))

;; The KeyState UGen requires an integer argument.  This helper can
;; generate the integer all aphanumeric characters.  The user may have
;; to reconfigure for a local keyboard by setting the global value
;; KeyStateIntegerOffsets.

(define (KeyStateInteger z)
  (if (string? z)
      (KeyStateInteger (string-ref z 0))
      (let loop ((c '("1234567890" "qwertyuiop" "asdfghjkl" "zxcvbnm"))
		 (i (KeyStateIntegerOffsets)) 
		 (b (map char->integer '(#\1 #\q #\a #\z))))
	(if (null? c)
	    (error "KeyStateInteger: illegal input" z)
	    (let ((n (string-index (car c) z)))
	      (if n 
		  (+ n (car i))
		  (loop (cdr c) (cdr i) (cdr b))))))))

